package com.lonely.fx.tree_view;

import com.lonely.fx.tree_view.entity.TestDragDto;
import javafx.application.Application;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.scene.Scene;
import javafx.scene.control.*;
import javafx.scene.image.Image;
import javafx.scene.image.ImageView;
import javafx.scene.input.*;
import javafx.scene.layout.*;
import javafx.scene.paint.Color;
import javafx.stage.Stage;
import javafx.util.Callback;

/**
 * @date: 2022-08-03 14:30
 * @author: ztkj-hzb
 * @description: treeview 拖拽效果演示
 **/
public class TreeViewWithDragSettingMain extends Application {

    public static void main(String[] args) {
        launch(args);
    }

    /**
     *
     */
    @Override
    public void start(Stage primaryStage) throws Exception {


        AnchorPane anchorPane = new AnchorPane();

        //创建TreeView
        TreeView<String> treeView = new TreeView<>();

        //准备数据

        //创建根节点
        TreeItem<String> root = new TreeItem<>("中国");

        TreeItem<String> hb = new TreeItem<>("湖北省");
        TreeItem<String> hb_1 = new TreeItem<>("鄂州市");
        TreeItem<String> hb_2 = new TreeItem<>("武汉市");
        TreeItem<String> hb_3 = new TreeItem<>("襄樊市");
        TreeItem<String> hb_4 = new TreeItem<>("黄冈市");

        //添加子节点
        hb.getChildren().addAll(hb_1, hb_2, hb_3, hb_4);

        TreeItem<String> gd = new TreeItem<>("广东省");
        TreeItem<String> gd_1 = new TreeItem<>("广州市");
        TreeItem<String> gd_2 = new TreeItem<>("深圳市");
        TreeItem<String> gd_3 = new TreeItem<>("东莞市");
        gd.getChildren().addAll(gd_1, gd_2, gd_3);

        TreeItem<String> hn = new TreeItem<>("湖南省");
        TreeItem<String> hn_1 = new TreeItem<>("长沙市");
        TreeItem<String> hn_2 = new TreeItem<>("岳阳市");
        hn.getChildren().addAll(hn_1, hn_2);

        root.getChildren().addAll(hb, gd, hn);

        //设置根节点
        treeView.setRoot(root);

        //设置宽高
        treeView.setPrefSize(300, 400);

        //全部展开
        expandOrShrink(root, true);


        //记录源数据
        TestDragDto testDragDto = new TestDragDto();

        treeView.setCellFactory(new Callback<TreeView<String>, TreeCell<String>>() {
            @Override
            public TreeCell<String> call(TreeView<String> param) {

                TreeCell<String> treeCell = new TreeCell<String>() {

                    /**
                     *
                     */
                    @Override
                    protected void updateItem(String item, boolean empty) {
                        super.updateItem(item, empty);

                        if (empty) {
                            this.setText(null);
                        }

                        this.setText(item);
                    }

                };

                treeCell.setOnDragDetected(new EventHandler<MouseEvent>() {


                    @Override
                    public void handle(MouseEvent event) {
                        Dragboard dragboard = treeCell.startDragAndDrop(TransferMode.MOVE);
                        ClipboardContent clipboardContent = new ClipboardContent();
                        clipboardContent.putString(String.format("%s-%s", treeCell.getIndex(), treeCell.getTreeItem().getValue()));
                        dragboard.setContent(clipboardContent);

                        testDragDto.setSourceIndex(treeCell.getIndex());
                        testDragDto.setSourceData(treeCell.getTreeItem().getValue());
                        testDragDto.setSourceTreeItem(treeCell.getTreeItem());
                    }
                });


                treeCell.setOnDragOver(new EventHandler<DragEvent>() {
                    @Override
                    public void handle(DragEvent event) {
                        event.acceptTransferModes(event.getTransferMode());

                        //靠近底线时候显示下边框
                        if (event.getY() >= treeCell.getHeight() - 10 && event.getY() <= treeCell.getHeight()) {
                            //System.out.println("到达目标范围");

                            //设置下边框
                            treeCell.setBorder(new Border(new BorderStroke(Color.PINK, BorderStrokeStyle.SOLID,
                                    new CornerRadii(1), new BorderWidths(0, 0, 3, 0))));

                        }


                    }
                });

                treeCell.setOnDragEntered(new EventHandler<DragEvent>() {
                    @Override
                    public void handle(DragEvent event) {
                        //设置光标
                        //treeView.getFocusModel().focus(treeCell.getIndex());
                    }
                });

                //移出当前cell
                treeCell.setOnDragExited(new EventHandler<DragEvent>() {
                    @Override
                    public void handle(DragEvent event) {
                        treeCell.setBorder(null);
                    }
                });

                //松开拖拽时
                treeCell.setOnDragDropped(new EventHandler<DragEvent>() {
                    @Override
                    public void handle(DragEvent event) {
                        //获取剪切板内容
                        //Dragboard dragboard = event.getDragboard();
                        //String body = dragboard.getString();

                        String sourceData = testDragDto.getSourceData();

                        //在新位置添加数据

                        //新数据
                        TreeItem<String> newTreeItem = new TreeItem<>(sourceData);
                        if (!testDragDto.getSourceTreeItem().isLeaf()) {
                            //非叶子节点
                            for (TreeItem<String> child : testDragDto.getSourceTreeItem().getChildren()) {
                                //TODO 这里不谨慎，需要使用递归，自己完善
                                newTreeItem.getChildren().add(new TreeItem<>(child.getValue()));
                            }
                        }

                        if (!treeCell.getTreeItem().isLeaf()) {
                            //非叶子节点
                            treeCell.getTreeItem().getChildren().add(0, newTreeItem);
                        } else {
                            TreeItem<String> parent = treeCell.getTreeItem().getParent();
                            int index = parent.getChildren().indexOf(treeCell.getTreeItem());
                            parent.getChildren().add(index + 1, newTreeItem);
                        }


                        //删除源数据
                        testDragDto.getSourceTreeItem().getParent().getChildren().remove(testDragDto.getSourceTreeItem());

                    }
                });

                return treeCell;
            }
        });


        anchorPane.getChildren().addAll(treeView);
        //AnchorPane.setTopAnchor(treeView, 100.0);
        primaryStage.setScene(new Scene(anchorPane));
        primaryStage.setWidth(600);
        primaryStage.setHeight(500);
        primaryStage.show();


    }


    private void expandOrShrink(TreeItem<String> treeItem, boolean isExpand) {

        //如果是叶子节点，直接返回
        if (treeItem.isLeaf()) {
            return;
        }

        //非叶子节点,设置状态
        treeItem.setExpanded(isExpand);

        //获取下级节点
        for (TreeItem<String> child : treeItem.getChildren()) {
            expandOrShrink(child, isExpand);
        }

    }
}
